﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Includes;

namespace AsyncroneModule
{
   /// <summary>
   /// Class used to check submitted vital data for deviations
   /// </summary>
   public static class ValueCheck
   {
      /// <summary>
      /// Persists the provided vitalData, and returns a resultset
      /// </summary>
      /// <param name="tel"> Number of the patient </param>
      /// <param name="vitaData"> Values the patient submitted </param>
      /// <returns> 
      /// Name of patient and action value.
      /// Action value is:
      ///  0 for no deviation
      /// -1 for first deviation
      /// -2 for critical deviation
      /// -3 for successive deviation
      /// -9 if patient does not exist
      /// </returns>
      public static CallInfoAsync insertValues(String tel, Vitals vitaData) 
      {
         CallInfoAsync result = new CallInfoAsync();
         IPersistAsync persi  = new PersistAsync(); 
         Flags flags;
         VitalData vData;

         // Check whether patient exists
         if(!persi.isPatient(tel))
         {
            result.action = -9;
            return result;
         }

         // Get vData (to compare against) and flags (to determine action)
         vData = persi.getVData(tel);
         
         // Since he wrote an sms obviously he's been informed
         flags = persi.getFlags(tel);
         flags.info = true;
         persi.setFlags(tel,flags);

         // Get name of patient
         result.name = persi.getPatientName(tel);
        
         // Persist the Vitals
         persi.addVital(tel, vitaData);
       
         // Check for critical deviation
         if(((float)vitaData.blood  > ((float)vData.normalBlood  * (1 + vData.critDerBlood)) 
         || ((float)vitaData.blood  < ((float)vData.normalBlood  * (1 - vData.critDerBlood))))
         || ((float)vitaData.pulse  > ((float)vData.normalPulse  * (1 + vData.critDerPulse)) 
         || ((float)vitaData.pulse  < ((float)vData.normalPulse  * (1 - vData.critDerPulse))))
         || ((float)vitaData.weight > ((float)vData.normalWeight * (1 + vData.critDerWeight))
         || ((float)vitaData.weight < ((float)vData.normalWeight * (1 - vData.critDerWeight)))))
         {
               persi.addLog(tel, ("Kritische Abweichung der Vitalwerte, Nachricht INA0001 gesendet"));
               result.action = -2;
               return result;
         }


         // Check for deviation
         if(((float)vitaData.blood  > ((float)vData.normalBlood  * (1 + vData.derBlood)) 
         || ((float)vitaData.blood  < ((float)vData.normalBlood  * (1 - vData.derBlood))))
         || ((float)vitaData.pulse  > ((float)vData.normalPulse  * (1 + vData.derPulse)) 
         || ((float)vitaData.pulse  < ((float)vData.normalPulse  * (1 - vData.derPulse))))
         || ((float)vitaData.weight > ((float)vData.normalWeight * (1 + vData.derWeight))
         || ((float)vitaData.weight < ((float)vData.normalWeight * (1 - vData.derWeight)))))
         {
               // Deviation had been detected last time
               if(flags.rd){
                  persi.addLog(tel, ("Wiederholte Abweichung der Vitalwerte, Nachricht IP0003 gesendet und kr Flag gesetzt."));
                  flags.kr = true;
                  result.action = -3;
               }
               // First deviation has been detected
               else
               {      
                     persi.addLog(tel, ("Erste Abweichung der Vitalwerte, Nachricht IP0002 gesendet und rd Flag gesetzt."));                  
                     flags.rd = true;
                     result.action = -1;
               }
             
               // Persist the flags (since KR and RD might have changed)
               persi.setFlags(tel, flags);               
               return result;
         }
        
         // No deviation has been detected
         if(flags.rd){
               flags.rd = false;
               persi.setFlags(tel, flags);
         }

         result.action = 0;
         return result;
      }
   }
}
